package com.fsts.server;

import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JTextArea;

import com.fsts.entity.PrivateKey;
import com.fsts.entity.PublicKey;

/**
 * 
 * TC服务中心监听类
 * 
 * @version 1.0
 * @since JDK1.6(建议)
 */
public class TrustedCenter {
	
	private JTextArea infoTextArea;

	public List<TrustedCenterHandler> handlers = new ArrayList<TrustedCenterHandler>();

	/** 素数长度 */
	public static final int PRIME_LENGTH = 24;
	public static final int INIT_G = 5;
	
	private BigInteger p;
	private BigInteger q;
	private BigInteger d;
	private BigInteger n;
	private BigInteger e;
	private BigInteger g;
	private BigInteger z;
	
	public JTextArea getInfoTextArea() {
		return infoTextArea;
	}

	public void setInfoTextArea(JTextArea infoTextArea) {
		this.infoTextArea = infoTextArea;
	}
	
	public TrustedCenter(JTextArea infoTextArea) {
		this.infoTextArea = infoTextArea;
	}
	/**
	 * 初始化生成系统参数
	 */
	public void init() {
		// (1): 随机产生2个不同的大素数p和q，两数长度大致相等，要求其值>10100；
		p = BigInteger.probablePrime(PRIME_LENGTH, new Random());
		infoTextArea.append("生成大素数p:" + Long.toHexString(Long.parseLong(p.toString())).toUpperCase() + "\n");
		q = BigInteger.probablePrime(PRIME_LENGTH, new Random(1));
		infoTextArea.append("生成大素数q:" + Long.toHexString(Long.parseLong(q.toString())).toUpperCase() + "\n");
		// (2)计算n = p*q和z = ( p-1 ) ( q-1 )；
		n = p.multiply(q);
		infoTextArea.append("计算参数n:" +  Long.toHexString(Long.parseLong(n.toString())).toUpperCase() + "\n");
		z = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
		// (3)随机选取一个整数e，1<e<z，且满足gcd (e, z) = 1；
		e = BigInteger.probablePrime(8, new Random());
		infoTextArea.append("选取参数e:" + Long.toHexString(Long.parseLong(e.toString())).toUpperCase() + "\n");
		while (true) {
			if (!z.mod(e).equals(BigInteger.ZERO)) {
				break;
			}
			e = e.add(BigInteger.ONE);
		}
		// (4)用欧几里得扩展算法计算d，1<d<z，使其满足 e d ≡ 1 (mod z )
		d = e.modInverse(z);
		infoTextArea.append("计算参数d:" + Long.toHexString(Long.parseLong(d.toString())).toUpperCase() + "\n");

		// (5)选择一个整数g，作为有限域Zp中的基元可信中心公开{n , e , g}，保密{p , q , d}
		g = new BigInteger(INIT_G + "");
		infoTextArea.append("选取参数g:" + Long.toHexString(Long.parseLong(g.toString())).toUpperCase() + "\n");
		infoTextArea.append("初始化成功\n");
		TCDao td = new TCDao();
		td.addPublicKey(new PublicKey(n, e, g));
		td.addPrivateKey(new PrivateKey(p, q, d));
	}

	/**
	 * 
	 */
	public void listener() {
		ServerSocket ss = null;
		try {
			TrustedCenter server = new TrustedCenter(this.infoTextArea);
			ss = new ServerSocket(9999);
			System.out.println("监听在9999端口...");
			Socket s = null;
			while (true) {
				s = ss.accept(); // 循环接收用户的请求
				System.out.println("获取一个连接：地址为--> " + s.getInetAddress());
				TrustedCenterHandler h = new TrustedCenterHandler(s);
				server.handlers.add(h);
				h.setHandlers(server.handlers);
				Thread t = new Thread(h);
				t.start();
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
